home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / Tools / Dev / Orbit_SRC / orbit.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-27  |  14.2 KB  |  715 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5. */
  6. /*
  7.  
  8. ORBIT, a freeware space combat simulator
  9. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  10.  
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  24.  
  25. */
  26.  
  27. #define ALLOCATE
  28. #include "orbit.h"
  29.  
  30. int tm, frames, total_frames;
  31.  
  32. int main (int argc, char **argv)
  33. {
  34.   /* Kick random number generator */
  35.   srand (time(NULL));
  36.  
  37.   /* Check for joystick */
  38.   InitJoy();
  39.  
  40.   /* Init the performance timer */
  41.   InitTimer();
  42.  
  43.   /* Set up the player viewpoint, etc */
  44.   InitPlayer();
  45.  
  46.   /* Initialize all sorts of other stuff */
  47.   InitStuff();
  48.  
  49.   /* Open a window */
  50.   OpenWindow (argc, argv);
  51.  
  52.   frames = 0;
  53.   total_frames = 1;
  54.   tm = time(NULL);
  55.  
  56.   /* Loop forever */
  57.   glutMainLoop();
  58.  
  59.   return(0);
  60. }
  61.  
  62. void OpenWindow (int argc, char **argv)
  63. /*
  64.  *  Open a window
  65.  */
  66. {
  67.   char *p;
  68.  
  69.   glutInit (&argc, argv);
  70.   glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  71.  
  72.   glutInitWindowPosition (0, 0);
  73.   glutInitWindowSize (ScreenWidth, ScreenHeight);
  74.  
  75.   if (!strcasecmp (gamemode, "no"))
  76.   {
  77.     glutCreateWindow ("Orbit");
  78.   }
  79.   else
  80.   {
  81.     glutGameModeString (gamemode);
  82.     glutEnterGameMode();
  83.   }
  84.  
  85.   if (fullscreen) glutFullScreen ();
  86.  
  87.   glutDisplayFunc (DrawScene);
  88.   glutReshapeFunc (Reshape);
  89.  
  90.   /* Define lights, etc */
  91.   Lights();
  92.   glEnable (GL_DEPTH_TEST);
  93.   glEnable (GL_CULL_FACE);
  94.  
  95.   /* Put up some driver info */
  96.   p = (char *) glGetString (GL_VENDOR);
  97.   Log ("OpenWindow: OpenGL vendor: %s", p);
  98.   p = (char *) glGetString (GL_RENDERER);
  99.   Log ("OpenWindow: OpenGL renderer: %s", p);
  100.   p = (char *) glGetString (GL_VERSION);
  101.   Log ("OpenWindow: OpenGL version: %s", p);
  102. }
  103.  
  104. void CreateUniverse ()
  105. /*
  106.  *  And Then There Was Light
  107.  */
  108. {
  109.   /* Initialize keyboard */
  110.   InitKeyboard();
  111.  
  112.   /* Initialize the mouse */
  113.   InitMouse();
  114.  
  115.   /* Construct the starfield display list */
  116.   MakeStarList();
  117.  
  118.   /* Initialize planets */
  119.   InitPlanets(); 
  120.   
  121.   /* Init AC3D textures */ 
  122.   InitTextures();
  123.  
  124.   /* Ring stuff */
  125.   InitRings();
  126.  
  127.   /* Init the HUD */
  128.   InitHud();
  129.  
  130.   /* Initialize sound */
  131.   InitSound();
  132.  
  133.   /* Initialize the network */
  134.   InitNetwork();
  135.  
  136.   /* Okay, load a mission */
  137.   if (mission.fn[0] != 0)
  138.   {
  139.     /* Load mission from prefs file */
  140.     ReadMission (mission.fn);
  141.   }
  142.   else
  143.   {
  144.     /* Read default mission */
  145.     ReadMission ("train01.msn");
  146.   }
  147. }
  148.  
  149. void DrawScene()
  150. /*
  151.  *  Draw the scene
  152.  */
  153. {
  154.   double v[3], t;
  155.  
  156.   /* if (am_client) Log ("!!! DrawScene()"); */
  157.  
  158.   /* Are we still initializing? */
  159.   if (state == STATE_INIT)
  160.   {
  161.     /* Create everything */
  162.     CreateUniverse();
  163.  
  164.     /* Mark new state */
  165.     state = STATE_NORMAL;
  166.   }
  167.  
  168.   /* Figure out how many seconds (in deltaT) have elapsed since the last
  169.     time we were here */
  170.   /* if (am_client) Log ("!!! DeltaTime()"); */
  171.   DeltaTime();
  172.  
  173.   /* Handle the network */
  174.   /* if (am_client) Log ("!!! DoNetwork()"); */
  175.   DoNetwork();
  176.  
  177.   /* Read the keyboard */
  178.   /* if (am_client) Log ("!!! Keyboard()"); */
  179.   Keyboard();
  180.  
  181.   /* Handle the joystick */
  182.   /* if (am_client) Log ("!!! Joystick()"); */
  183.   if (joy_available && !paused) JoyStick();
  184.  
  185.   /* Do the mouse */
  186.   /* if (am_client) Log ("!!! DoMouse()"); */
  187.   if (mouse_control && !paused) DoMouse();
  188.  
  189.   /* Move the planets */
  190.   if (orbit) MovePlanets();
  191.  
  192.   /* Move the player */
  193.   /* if (am_client) Log ("!!! UpdatePlayer()"); */
  194.   if (!paused) UpdatePlayer ();
  195.  
  196.   /* Move the targets */
  197.   /* if (am_client) Log ("!!! MoveTargets()"); */
  198.   if (!paused) MoveTargets ();
  199.  
  200.   /* Move the missiles */
  201.   /* if (am_client) Log ("!!! MoveMissiles()"); */
  202.   if (!paused) MoveMissiles ();
  203.  
  204.   /* Process any outstanding events */
  205.   /* if (am_client) Log ("!!! DoEvents()"); */
  206.   DoEvents();
  207.  
  208.   /* Clear the screen */
  209.   if (palette_flash == 2)
  210.   {
  211.     /* Flash red */
  212.     palette_flash = 0;
  213.     glClearColor (1.0, 0.0, 0.0, 0.0);
  214.   }
  215.   else if (palette_flash > 0)
  216.   {
  217.     /* Flash white */
  218.     palette_flash = 0;
  219.     glClearColor (1.0, 1.0, 1.0, 0.0);
  220.   }
  221.   else
  222.   {
  223.     glClearColor (0.0, 0.0, 0.0, 0.0);
  224.   }
  225.   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  226.  
  227.   /* Set up viewing transformation */
  228.   glMatrixMode (GL_MODELVIEW);
  229.   glLoadIdentity();
  230.  
  231.   /* Compute a point along line of sight */
  232.   Vadd (v, player.pos, player.view);
  233.  
  234.   gluLookAt (0.0, 0.0, 0.0,
  235.   player.view[0], player.view[1], player.view[2],
  236.   player.up[0], player.up[1], player.up[2]);
  237.  
  238.   /* Draw the star field here */
  239.   if (starfield) DrawStars();
  240.  
  241.   Lights();
  242.  
  243.   /* Draw the world */
  244.   /* if (am_client) Log ("!!! DrawWorld()"); */
  245.   DrawWorld();
  246.  
  247.   /* Do some 2-D stuff just to prove I can */
  248.   /* if (am_client) Log ("!!! Hud()"); */
  249.   Hud();
  250.  
  251.   /* Swap buffers */
  252.   glFlush();
  253.   glutSwapBuffers();
  254.  
  255.   /* Keep on Displayin' */
  256.   glutPostRedisplay();
  257.  
  258.   frames++;
  259.   total_frames++;
  260.   if (0 == (frames % 50))
  261.   {
  262.     t = Time();
  263.  
  264.     fps = 50.0 / t;
  265.     frames = 0;
  266.  
  267.     recv_bps = ((double) recv_bytes) / t;
  268.     xmit_bps = ((double) xmit_bytes) / t;
  269.     recv_bytes = xmit_bytes = 0;
  270.  
  271.     tm = time (NULL);
  272.   }
  273. }
  274.  
  275. void DrawSplash()
  276. /*
  277.  *  Draw minimal screen for startup splash
  278.  */
  279. {
  280.   double v[3];
  281.   int tmphud;
  282.  
  283.   Reshape (ScreenWidth, ScreenHeight);
  284.  
  285.   glClearColor (0.0, 0.0, 0.0, 0.0);
  286.   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  287.  
  288.   /* Set up viewing transformation */
  289.   glMatrixMode (GL_MODELVIEW);
  290.   glLoadIdentity();
  291.  
  292.   /* Compute a point along line of sight */
  293.   Vadd (v, player.pos, player.view);
  294.  
  295.   gluLookAt (player.pos[0], player.pos[1], player.pos[2],
  296.   v[0], v[1], v[2],
  297.   player.up[0], player.up[1], player.up[2]);
  298.  
  299.   /* Draw the star field here */
  300.   /* if (starfield) DrawStars(); */
  301.  
  302.   /* Do some 2-D stuff just to prove I can */
  303.   tmphud = drawhud;
  304.   drawhud = 0;
  305.   Hud();
  306.   drawhud = tmphud;
  307.  
  308.   /* Swap buffers */
  309.   glFlush();
  310.   glutSwapBuffers();
  311.  
  312.   /* Keep on Displayin' */
  313.   glutPostRedisplay();
  314. }
  315.  
  316. void Reshape (GLsizei w, GLsizei h)
  317. {
  318.   double ratio;
  319.  
  320.   ScreenWidth = w;
  321.   ScreenHeight = h;
  322.   ratio = (double) w / (double) h;
  323.  
  324.   glMatrixMode (GL_PROJECTION);
  325.   glLoadIdentity();
  326.   gluPerspective (fov, ratio, clipnear, clipfar);
  327.   glMatrixMode (GL_MODELVIEW);
  328.   glViewport (0, 0, w, h);
  329.  
  330.   /* Recompute the HUD stuff */
  331.   InitHud();
  332. }
  333.  
  334. static float MaterialColor[] = {
  335.   1.0, 1.0, 1.0, 1.0}
  336. ;
  337. static float JunkColor[] = {
  338.   0.7, 0.7, 0.7, 1.0}
  339. ;
  340. static double MissileColor[] = {
  341.   1.0, 1.0, 0.0, 1.0}
  342. ;
  343. static float TargetColor[] = {
  344.   1.0, 0.5, 0.0, 1.0}
  345. ;
  346.  
  347. void DrawWorld ()
  348. /*
  349.  *  Draw the world
  350.  */
  351. {
  352.   /* Draw planet */
  353.   DrawPlanets();
  354.  
  355.   /* Draw space junk */
  356.   if (junk)
  357.   {
  358.     glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, JunkColor);
  359.     Junk();
  360.   }
  361.  
  362.   /* Draw missiles */
  363.   DrawMissiles ();
  364.  
  365.   /* Draw targets */
  366.   DrawTargets();
  367.  
  368.   /* Draw explosions */
  369.   DrawBooms ();
  370.  
  371.   /* Draw planetary rings */
  372.   DrawRings();
  373.  
  374.   /* Show names of things */
  375.   if (show_names) ShowNames();
  376. }
  377.  
  378. void Print (void *font, char *string)
  379. {
  380.   int len, i;
  381.  
  382.   len = strlen (string);
  383.   for (i=0; i<len; i++)
  384.   {
  385.     glutBitmapCharacter (font, string[i]);
  386.   }
  387. }
  388.  
  389. void InitStuff()
  390. /*
  391.  *  Misc initilization
  392.  *
  393.  *  DON'T PUT ANY OPENGL STUFF IN HERE!  THE WINDOW HASN'T EVEN BEEN OPENED YET!!!
  394.  */
  395. {
  396.   vulnerable = 1;
  397.   joy_throttle = 0;
  398.   deadzone = DEADZONE;
  399.   absT = 0.0;
  400.   starfield = 1;
  401.   drawhud = 1;
  402.   showfps = 0;
  403.   gravity = 0;
  404.   junk = 1;
  405.   palette_flash = 0;
  406.   sound = 1;
  407.   show_names = 0;
  408.   screen_shot_num = 0;
  409.   rings = 1;
  410.   textures = 1;
  411.   mission.fn[0] = 0;
  412.   paused = 0;
  413.   mouse_control = 1;
  414.   strcpy (gamemode, "no");
  415.   fullscreen = 0;
  416.   player.flightmodel = FLIGHT_NEWTONIAN;
  417.   strcpy (player.name, "Sparky");
  418.   strcpy (player.model, "light2.tri");
  419.   ring_sectors = RING_SECTORS;
  420.   stacks0 = 3;
  421.   slices0 = 7;
  422.   stacks1 = 6;
  423.   slices1 = 13;
  424.   stacks2 = 12;
  425.   slices2 = 24;
  426.   mouse.flipx = 0;
  427.   mouse.flipy = 0;
  428.   state = STATE_INIT;
  429.   realdistances = 0;
  430.   fov = 90.0;
  431.   text.yes = 0;
  432.   text.buf[0] = 0;
  433.   text.index = 0;
  434.   text.prompt[0] = 0;
  435.   text.func = NULL;
  436.   fullstop = 1;
  437.   player.still = 1;
  438.   draw_orbits = 0;
  439.   orbit = 0;
  440.   compression = 1.0; 
  441.   player.viewlock = 0.0; 
  442.   server.port = ORBIT_PORT; 
  443.   superwarp = 1; 
  444.   clipnear = 0.01; 
  445.   clipfar = 100000.0; 
  446.   /* clipnear = 0.001; 
  447.  clipfar = 100000.0; */
  448.  
  449.   /* Set initial screen size */
  450.   ScreenWidth = SCREENWIDTH;
  451.   ScreenHeight = SCREENHEIGHT;
  452.  
  453.   /* Initialize the log file */
  454.   InitLog();
  455.  
  456.   Log ("InitStuff: ORBIT Version %s", VERSION);
  457.  
  458.   /* Read the preferences file */
  459.   ReadPrefs();
  460.  
  461.   /* Read stars data file */
  462.   ReadStars();
  463.  
  464.   /* Initialize the message console */
  465.   InitConsole();
  466.  
  467.   /* Initialize the message system */
  468.   InitMessage();
  469.  
  470.   /* Initialize the object models */
  471.   InitModels();
  472.  
  473.   /* Initialize the missiles */
  474.   InitMissiles();
  475.  
  476.   /* Weapons */
  477.   InitWeapons();
  478.  
  479.   /* Initialize explosions */
  480.   InitBooms();
  481.  
  482.   /* Initialize lights */
  483.   InitLights();
  484.  
  485.   /* Initialize targets */
  486.   InitTargets();
  487.  
  488.   /* Initialize events */
  489.   InitEvents();
  490.  
  491.   /* Self-promotion */
  492.   Cprint ("Orbit %s, by Steve Belczyk <orbit@genesis.nred.ma.us>", VERSION);
  493.   Cprint ("http://genesis.ne.mediaone.net/orbit");
  494.   #ifdef AMIGA_VERSION
  495.   Cprint ("Amiga port %s, by Oliver Gantert <lucyg@t-online.de>", AMIGA_VERSION);
  496.   Cprint ("http://home.t-online.de/home/LucyG");
  497.   #endif
  498. }
  499.  
  500. double Theta (double *v)
  501. /*
  502.  *  Compute angle vector v points to
  503.  */
  504. {
  505.   double th;
  506.  
  507.   th = (double) acos ((double) v[0]);
  508.   th = th * 180.0 / 3.14159;
  509.   if (v[1] < 0.0) th = (-th);
  510.  
  511.   return (th);
  512. }
  513.  
  514. #ifdef WIN32MOUSE
  515. Mouse()
  516. /*
  517.  *  Process the mouse
  518.  */
  519. {
  520.   GetCursorPos (&point);
  521.   mouse_x = point.x;
  522.   mouse_y = point.y;
  523.  
  524.   if (mouse_x > last_mouse_x) player.move_right = 1.0;
  525.   if (mouse_x < last_mouse_x) player.move_left = 1.0;
  526.   if (mouse_y > last_mouse_y) player.move_up = 1.0;
  527.   if (mouse_y < last_mouse_y) player.move_down = 1.0;
  528.  
  529.   last_mouse_x = last_mouse_y = 400;
  530.  
  531.   SetCursorPos (400, 400);
  532. }
  533. #endif
  534.  
  535. void Gravity (double *deltav, double *pos)
  536. /*
  537.  *  Compute change in velocity due to planet's gravity
  538.  */
  539. {
  540.   double r, rr, dv, dp[3], v[3];
  541.   int p;
  542.  
  543.   deltav[0] = deltav[1] = deltav[2] = 0.0;
  544.  
  545.   for (p=0; p<NPLANETS; p++)
  546.   {
  547.     /* Distance to planet */
  548.     Vsub (dp, planet[p].pos, pos);
  549.  
  550.     rr = Mag2 (dp);
  551.  
  552.     /* Ignore planets too far away */
  553.     if (rr > 200.0*200.0) continue;
  554.  
  555.     /* Don't stand so close to me */
  556.     if (rr < RMIN) rr = RMIN;
  557.  
  558.     r = sqrt (rr);
  559.     dv = G * planet[p].mass / rr;
  560.  
  561.     Vmul (v, dp, dv);
  562.     Vdiv (v, v, r);
  563.  
  564.     Vadd (deltav, deltav, v);
  565.   }
  566. }
  567.  
  568. void Junk()
  569. /*
  570.  *  Draw space junk to give visual cues of motion
  571.  */
  572. {
  573.   double x, y, z;
  574.  
  575.   glDisable (GL_LIGHTING);
  576.   glDisable (GL_CULL_FACE);
  577.   glColor3d (0.5, 0.5, 0.5);
  578.  
  579.   x = (double) (int) player.pos[0];
  580.   y = (double) (int) player.pos[1];
  581.   z = (double) (int) player.pos[2];
  582.  
  583.   PieceOfJunk (x+0.5, y+0.5, z+0.5);
  584.   PieceOfJunk (x-0.5, y+0.5, z+0.5);
  585.   PieceOfJunk (x-0.5, y-0.5, z+0.5);
  586.   PieceOfJunk (x+0.5, y-0.5, z+0.5);
  587.  
  588.   PieceOfJunk (x+0.5, y+0.5, z-0.5);
  589.   PieceOfJunk (x-0.5, y+0.5, z-0.5);
  590.   PieceOfJunk (x-0.5, y-0.5, z-0.5);
  591.   PieceOfJunk (x+0.5, y-0.5, z-0.5);
  592.  
  593.   glEnable (GL_CULL_FACE);
  594.   glEnable (GL_LIGHTING);
  595. }
  596.  
  597. void PieceOfJunk (double x, double y, double z)
  598. /*
  599.  *  Draw a single piece of space junk
  600.  */
  601. {
  602.   double r, v1[3], v2[3];
  603.  
  604.   glPushMatrix();
  605.  
  606.   /* Figure how much to spin junk */
  607.   r = absT - ((double)(int)absT);
  608.   r = 360.0 * r;
  609.  
  610.   /* Draw the junk */
  611.   v1[0] = x; v1[1] = y; v1[2] = z;
  612.   Vsub (v2, v1, player.pos);
  613.   glTranslated (v2[0], v2[1], v2[2]);
  614.  
  615.   glRotated (r, 0.0, 1.0, 0.0);
  616.   glBegin (GL_POLYGON);
  617.   glNormal3d (0.0, 0.0, 1.0);
  618.   glVertex3d (-.003, -.003, 0.0);
  619.   glVertex3d (.003, -.003, 0.0);
  620.   glVertex3d (0.0, .003, 0.0);
  621.   glEnd();
  622.  
  623.   glPopMatrix();
  624. }
  625.  
  626. void ShowNames()
  627. /*
  628.  *  Show the names of things
  629.  */
  630. {
  631.   glDisable (GL_DEPTH_TEST);
  632.   glDisable (GL_LIGHTING);
  633.   ShowPlanetNames();
  634.   ShowTargetNames();
  635.   glEnable (GL_LIGHTING);
  636.   glEnable (GL_DEPTH_TEST);
  637. }
  638.  
  639. void LookAt (double *view, double *up)
  640. /*
  641.  *  Set up a transformation so a model will be drawn pointing the
  642.  *  right direction (view) and upright (up)
  643.  */
  644. {
  645.   double v1[3], v2[3], cos, th, thd, up2[3];
  646.  
  647.   /*
  648.   *  This thing is really ugly and inefficient.  It does sqrt's,
  649.   *  sin's, cos's, acos's, and asin's like there's no tomorrow.
  650.   *
  651.   *  In theory we should be able to build a little matrix like
  652.   *  gluLookAt() does, but I could never get that to work.  I
  653.   *  suspect what's needed is the inverse or transpose of the
  654.   *  gluLookAt() matrix, but I don't understand linear algebra
  655.   *  well enough to know.
  656.   *
  657.   *  If you can improve this thing please let me know.
  658.   */
  659.  
  660.   /* Make vector along positive X axis */
  661.   v1[0] = 1.0;
  662.   v1[1] = 0.0;
  663.   v1[2] = 0.0;
  664.  
  665.   /* Cross-product of X-axis and view vector is vector to
  666.     rotate about */
  667.   Crossp (v2, v1, view);
  668.  
  669.   /* Check for special case of null v2 (vectors are the same) */
  670.   if (0.0 == Mag2 (v2))
  671.   {
  672.     v2[1] = 1.0;
  673.   }
  674.  
  675.   /* Get cosine of angle between X axis and view vector */
  676.   cos = Dotp (view, v1);
  677.  
  678.   /* Normalize the vector to rotate about */
  679.   Normalize (v2);
  680.  
  681.   /* Compute angle to rotate */
  682.   th = acos (cos);
  683.   thd = th * 180.0 / 3.1415926535;
  684.  
  685.   /* Now we've got the model pointed in the right direction,
  686.     but the up vector is probably wrong.  This is the only
  687.     way I could think of to do this but boy it's ugly. */
  688.  
  689.   /* Figure out new up vector in up2 */
  690.   v1[0] = v1[1] = 0.0;
  691.   v1[2] = 1.0;
  692.   RotateAbout (up2, v1, v2, -th);
  693.   Normalize (up2);
  694.  
  695.   /* Rotate */
  696.   glRotated (thd, v2[0], v2[1], v2[2]);
  697.  
  698.   /* Cross product of current up and desired up is vector
  699.     to rotate about */
  700.   Crossp (v2, up2, up);
  701.  
  702.   /* If v2 is null, we're already facing the right way */
  703.   if (0.0 == Mag2 (v2)) return;
  704.  
  705.   Normalize (v2);
  706.   thd = acos (Dotp (up2, up)) * 180.0 / 3.1415926535;
  707.  
  708.   /* We rotate around the (rotated) view vector or negative view
  709.     vector depending which way v2 points */
  710.   if (Dotp (v2, view) > 0.0)
  711.   glRotated (thd, 1.0, 0.0, 0.0);
  712.   else
  713.   glRotated (thd, -1.0, 0.0, 0.0);
  714. }
  715.